﻿using Kingdee.BOS.WebApi.Client;
using Kingdee.BOS.WebApi.Client.Log;
using Kingdee.BOS.WebApi.DataEntities;
using KingdessServices.Model;
using log4net;
using Microsoft.Ajax.Utilities;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Reflection;
using System.Web;
using System.Web.Http;

namespace KingWeb.Controllers
{

    public class KingdessController : ApiController
    {
        private static readonly ILog _log = LogManager.GetLogger(typeof(KingdessController));

        // GET: Kingdess
        /// <summary>
        /// 转发服务
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public ApiResult RelayServices(RelayModel model)
        {
            string acctid = ConfigurationManager.AppSettings["X-KDApi-AcctID"];
             string userName = ConfigurationManager.AppSettings["X-KDApi-UserName"];
              string appId = ConfigurationManager.AppSettings["X-KDApi-AppID"];
              string appSec = ConfigurationManager.AppSettings["X-KDApi-AppSec"];
             string serverUrl = ConfigurationManager.AppSettings["X-KDApi-ServerUrl"];
        var paramjson = JsonConvert.SerializeObject(model);
            _log.Info(DateTime.Now.ToString() + "请求参数：" + paramjson);
            Random random = new Random();
            var Number = "SXY" + DateTime.Now.ToString("yyyyMMddHHmmss" + random.Next(1, 100));
            if (string.IsNullOrEmpty(model.OperateType) ||  string.IsNullOrEmpty(model.ParamJson))
            {
                _log.Info("参数为空，请仔细核查参数，请求参数编号：" + Number); 
                return new ApiResult(ApiErrorCode.Fail, "传参异常，请重新核对，请求参数编号：" + Number);
            }

            try
            {
                /*  return new ApiResult(ApiErrorCode.Fail, "未正常链接金蝶服务，请联系管理员：" + Number + ",初始化：" + clienterjson, reporesult);*/
                // 引用SDK组件Kingdee.BOS.WebApi.Client.dll; SDK下载地址：https://openapi.open.kingdee.com/ApiSdkCenter
                var client = new K3CloudApi();
                // 初始化登录认证，appID、appSec可在"第三方系统登录授权"中获取

                //client.InitClient(acctid, appId, appSec, userName, 2052, "100", serverUrl);

                client.InitClient("67c92ef74626c2", "305775_Q+aO5zstRqB85V+HX45KQy9K0tXd1KMH", "abb5012278544909a6ff975e0d9c2d52", "赵龙", 2052, "100", "http://kingdeetest.xjtianlai.com/k3cloud/");
                /* List<List<object>> results = client.ExecuteBillQuery("{\"FormId\":\"SAL_OUTSTOCK\",\"FieldKeys\":\"11\",\"FilterString\":[{\"FieldName\":\"FSalesManID.FName\",\"Compare\":\"67\",\"Value\":\"万桂珍\",\"Left\":\"(\",\"Right\":\")\",\"Logic\":\"0\"}],\"OrderString\":\"\",\"TopRowCount\":0,\"StartRow\":0,\"Limit\":2000,\"SubSystemId\":\"\"}"); */
                var clienterjson = JsonConvert.SerializeObject(client);
                RepoResult reporesult = client.CheckAuthInfo();
                if (reporesult.ResponseStatus.IsSuccess)
                {
                    var kingresult = "";
                    switch (model.OperateType.ToLower())
                    {
                        case "save": 
                            kingresult = client.Save(model.MethodName, model.ParamJson);
                            break;
                        case "flexsave": 
                            kingresult = client.FlexSave(model.MethodName, model.ParamJson);
                            break;
                        case "groupsave": 
                            kingresult = client.GroupSave(model.MethodName, model.ParamJson);
                            break;
                        case "batchsave": 
                            kingresult = client.BatchSave(model.MethodName, model.ParamJson);
                            break;
                        case "submit":
                            kingresult = client.Submit(model.MethodName, model.ParamJson);
                            break;
                        case "unaudit":
                            kingresult = client.UnAudit(model.MethodName, model.ParamJson);
                            break;
                        case "audit":
                            kingresult = client.Audit(model.MethodName, model.ParamJson);
                            break;
                        case "delete":
                            kingresult = client.Delete(model.MethodName, model.ParamJson);
                            break;
                        case "groupdelete":
                            kingresult = client.GroupDelete(model.ParamJson);
                            break;
                        case "view":
                            kingresult = client.View(model.MethodName, model.ParamJson);
                            break;
                        case "billquery":
                            kingresult = client.BillQuery(model.ParamJson);
                            break;
                        case "push":
                            kingresult = client.Push(model.MethodName, model.ParamJson);
                            break;
                        case "draft":
                            kingresult = client.Draft(model.MethodName, model.ParamJson);
                            break;
                        case "query":
                            kingresult = client.QueryBusinessInfo("{\"FormId\":\"SAL_OUTSTOCK\"}");
                            break;
                        default:
                            break;
                    }
                    if (string.IsNullOrEmpty(kingresult))
                    {
                        _log.Info("未找到操作方法，请联系管理员：" + Number);
                        return new ApiResult(ApiErrorCode.Fail, "未找到操作方法，请联系管理员：" + Number);
                    }
                    else
                    {
                        _log.Info("请求金蝶返回结果为：" + kingresult);
                    }
                    var processresult = false;
                    #region MyRegion
                    /*var resuljson = JObject.Parse(kingresult);
                    var queryNode = resuljson.SelectToken("$..IsSuccess");
                    if (queryNode != null)
                    {
                        processresult = queryNode.Value<Boolean>();
                    }*/
                    #region 优化后的结果解析 
                    processresult = CheckKingdeeApiSuccess(kingresult); 
                    #endregion

                    #endregion

                    _log.Info(processresult ? "转发服务成功：" + Number : "转发服务失败" + Number + "，请求返回参数："+ kingresult);
                    return new ApiResult(processresult ? ApiErrorCode.OK : ApiErrorCode.Fail, processresult ? "转发服务成功：" + Number : "转发服务失败" + Number, kingresult);
                }
                else
                {
                    _log.Info("未正常链接金蝶服务，请联系管理员：" + Number + ",初始化：" + clienterjson);
                    return new ApiResult(ApiErrorCode.Fail, "未正常链接金蝶服务，请联系管理员：" + Number + ",初始化：" + clienterjson, reporesult);
                }
            }
            catch (Exception ex)
            {
                _log.Error("服务转发转发异常，异常信息如下：" + ex.Message + "，异常处理编号" + Number,ex);
                return new ApiResult(ApiErrorCode.Error, "服务转发转发异常，异常信息如下：" + ex.Message + "，异常处理编号" + Number, ex);
            }

        }

        /// <summary>
        /// 校验返回结果是否正常
        /// </summary>
        /// <param name="jsonResponse"></param>
        /// <returns></returns>
        private bool CheckKingdeeApiSuccess(string jsonResponse)
        {
            try
            {
                var resultJson = JObject.Parse(jsonResponse);

                // 步骤1：精准路径匹配 `Result.ResponseStatus.IsSuccess` <a target="_blank" href="https://vip.kingdee.com/article/490771221039228672" class="hitref" data-title="金蝶云星空WebAPI接口说明书_V6.0" data-snippet='返回参数: 参数列表 参数含义 备注 ResponseStatus 操作状态{&quot;ResponseStatus&quot;:{&quot;ErrorCode&quot;:&quot;&quot;, &quot;IsSuccess&quot;:false, &quot;Errors&quot;:[{&quot;FieldName&quot;:&quot;&quot;, &quot;Message&quot;:...' data-url="https://vip.kingdee.com/article/490771221039228672">2</a>,{\"FieldName\":\"F...", "url": "https://blog.csdn.net/Monarchess_1234/article/details/122563222", "position": 3}<a target="_blank" href="https://blog.csdn.net/m0_66964946/article/details/135973175" class="hitref" data-title="金蝶云星空如何获取登录接口中返回的cookies php-CSDN博客" data-snippet='//对返回结果进行解析和校验. $json_response = json_decode($response);. if ($json_response -&gt;Result-&gt;ResponseStatus-&gt;IsSuccess). {. echo &quot;接口返回 ...' data-url="https://blog.csdn.net/m0_66964946/article/details/135973175">11</a><a target="_blank" href="http://112.16.172.14:3000/%E9%87%91%E8%9D%B6%E4%BA%91%E6%93%8D%E4%BD%9C/api%E8%B0%83%E7%94%A8%E9%87%91%E8%9D%B6.html" class="hitref" data-title="云星空API接口- 现工作文档" data-snippet='文档介绍. 金蝶云api. 程序 ... 返回结果进行解析和校验 res = json.loads(response) if res[&quot;Result&quot;][&quot;ResponseStatus&quot;][&quot;IsSuccess&quot;]: return True else: logging.' data-url="http://112.16.172.14:3000/%E9%87%91%E8%9D%B6%E4%BA%91%E6%93%8D%E4%BD%9C/api%E8%B0%83%E7%94%A8%E9%87%91%E8%9D%B6.html">15</a>
                var responseStatus = resultJson.SelectToken("Result.ResponseStatus");
                if (responseStatus == null)
                {
                    _log.Info("CheckKingdeeApiSuccess：未找到 ResponseStatus 节点");
                    return false;
                }

                // 步骤2：验证 `IsSuccess` 是否为布尔类型并取值 ,{\"FieldName\":\"F...", "url": "https://blog.csdn.net/Monarchess_1234/article/details/122563222", "position": 3}<a target="_blank" href="https://blog.csdn.net/m0_66964946/article/details/135973175" class="hitref" data-title="金蝶云星空如何获取登录接口中返回的cookies php-CSDN博客" data-snippet='//对返回结果进行解析和校验. $json_response = json_decode($response);. if ($json_response -&gt;Result-&gt;ResponseStatus-&gt;IsSuccess). {. echo &quot;接口返回 ...' data-url="https://blog.csdn.net/m0_66964946/article/details/135973175">11</a><a target="_blank" href="http://112.16.172.14:3000/%E9%87%91%E8%9D%B6%E4%BA%91%E6%93%8D%E4%BD%9C/api%E8%B0%83%E7%94%A8%E9%87%91%E8%9D%B6.html" class="hitref" data-title="云星空API接口- 现工作文档" data-snippet='文档介绍. 金蝶云api. 程序 ... 返回结果进行解析和校验 res = json.loads(response) if res[&quot;Result&quot;][&quot;ResponseStatus&quot;][&quot;IsSuccess&quot;]: return True else: logging.' data-url="http://112.16.172.14:3000/%E9%87%91%E8%9D%B6%E4%BA%91%E6%93%8D%E4%BD%9C/api%E8%B0%83%E7%94%A8%E9%87%91%E8%9D%B6.html">15</a>
                var isSuccessNode = responseStatus["IsSuccess"];
                if (isSuccessNode?.Type != JTokenType.Boolean)
                {
                    _log.Info("CheckKingdeeApiSuccess校验,IsSuccess 字段不存在或非布尔类型");
                    return false;
                }

                return isSuccessNode.Value<bool>();
            }
            catch (JsonException ex)
            {
                // 记录完整错误信息以便排查 <a target="_blank" href="https://mbd.baidu.com/newspage/data/dtlandingsuper?nid=dt_4509020929318574731" class="hitref" data-title="🚨金蝶服务端响应错误解决指南🚨" data-snippet='在使用金蝶软件时,如果遇到“服务端响应错误”的提示,不必惊慌,这里有一些实用的解决方案:1️⃣ 浏览器缓存问题:有时,浏览器缓存会导致响应错误。尝试清理浏览器缓存,例如使...' data-url="https://mbd.baidu.com/newspage/data/dtlandingsuper?nid=dt_4509020929318574731">5</a><a target="_blank" href="https://wenku.csdn.net/column/4gtqsd0sp6" class="hitref" data-title="【金蝶接口调试秘籍】:解决SOAP Web服务调试中的常见问题 ..." data-snippet='处理请求 返回响应 解析响应2.2 金蝶接口的技术栈分析2.2.1 金蝶接口的技术特点金蝶软件是中国领先的企业资源规划(ERP)解决方案提供商。金蝶接口一般遵循Web...' data-url="https://wenku.csdn.net/column/4gtqsd0sp6">7</a>
                _log.Error($"CheckKingdeeApiSuccess校验，JSON解析失败: {ex.Message}，原始响应：{jsonResponse}");
                return false;
            }
            catch (Exception ex)
            {
                _log.Error($"CheckKingdeeApiSuccess校验系统异常: {ex.Message}",ex);
                return false;
            }
        }


    }
}